package com.youbug.system.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youbug.common.constant.DicTypeContent;
import com.youbug.kefu.entity.Chat;
import com.youbug.system.entity.Dictionary;
import com.youbug.system.entity.Org;
import com.youbug.kefu.entity.ServiceTicket;
import com.youbug.common.exception.UploadException;
import com.youbug.kefu.service.*;
import com.youbug.common.vo.CommonTreeVo;
import com.youbug.system.vo.StatisticsVo;
import com.youbug.system.service.ICommonService;
import com.youbug.system.service.IDictionaryService;
import com.youbug.system.service.IOrgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Service
public class CommonService implements ICommonService {

    @Autowired
    private IOrgService orgService;

    @Autowired
    private IDictionaryService dictionaryService;

    @Autowired
    private IChatService chatService;
    @Autowired
    private IServiceTicketService serviceTicketService;

    @Override
    public List<CommonTreeVo> getOrgTree() {
        List<Org> orgs = orgService.getOrgs();

        return  getChildren(orgs);
    }

    @Override
    public String saveFile(MultipartFile file, String type) {
        String originalFilename = file.getOriginalFilename();

        if(!StringUtils.hasText(originalFilename)){
            throw  new UploadException("获取文件名失败");
        }
        String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.indexOf("."));

        saveLocalFile(type, newFileName, file);

        Dictionary netFileSource = dictionaryService.getOneByTypeAndCode(DicTypeContent.SYS_CONFIG, "netFileSource");

        String fileUrl = netFileSource.getValue() + type + "/" + newFileName;

        return fileUrl;
    }

    @Override
    public File saveLocalFile(String type, String newFileName, MultipartFile file) {

        Dictionary localSource = dictionaryService.getOneByTypeAndCode(DicTypeContent.SYS_CONFIG, "localFileSource");

        String rootFilePath = localSource.getValue() + type +"/";
        File savedFile;
        try {
            savedFile = new File(rootFilePath + newFileName);

            if(!savedFile.exists()){
                boolean b = savedFile.mkdirs();
            }
            file.transferTo(savedFile);
        } catch (IOException e) {
            e.printStackTrace();
            throw new UploadException("文件转存失败");
        }
        return savedFile;
    }

    @Override
    public List<CommonTreeVo> transForTreeSelect(List<Org> orgs) {
        List<CommonTreeVo> treeVos = new ArrayList<>(orgs.size());
        for (Org org : orgs){
            List<Org> subOrgs = org.getChildren();
            CommonTreeVo treeVo = new CommonTreeVo();
            treeVo.setLabel(org.getName());
            treeVo.setValue(String.valueOf(org.getId()));
            treeVo.setFullParentId(org.getFullParentId());
            treeVo.setFullParentName(org.getFullParentName());
            treeVo.setChildren(transForTreeSelect(subOrgs));
            treeVos.add(treeVo);
        }
        return treeVos;
    }

    @Override
    public StatisticsVo getStatistics() {

        QueryWrapper<Chat> wrapper = new QueryWrapper<>();
        QueryWrapper<ServiceTicket> ticketQueryWrapper = new QueryWrapper<>();

        DateTime offsetDay = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, -6);
        DateTime beginOfSetDay = DateUtil.beginOfDay(offsetDay);

        wrapper.gt("create_time", beginOfSetDay);
        ticketQueryWrapper.gt("create_time", beginOfSetDay);

        List<Chat> list = chatService.list(wrapper);
        List<ServiceTicket> tickets = serviceTicketService.list(ticketQueryWrapper);

        StatisticsVo vo = new StatisticsVo();

        makeDayCountAndSatisData(list, vo);
        makePerData(tickets, vo);
        return vo;
    }

    private void makeDayCountAndSatisData(List<Chat> list, StatisticsVo vo) {
        Map<String, Integer> dayCountMap = new LinkedHashMap<>();

        int satisfactionCount = 0;
        Integer satisfactionSum = 0;
        for (int i = 6; i >= 0; i--) {
            DateTime offsetDay = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, -i);
            String day = DateUtil.format(offsetDay, "yyyy-MM-dd");
            dayCountMap.put(day, 0);
        }
        for (Chat chat: list){

            String day = DateUtil.format(chat.getCreateTime(), "yyyy-MM-dd");
            Integer satisfaction = chat.getSatisfaction();
            if(satisfaction != null){
                satisfactionCount = satisfactionCount +1;
                satisfactionSum = satisfactionSum + satisfaction;
            }
            Integer integer = dayCountMap.get(day);
            if(integer != null){
                dayCountMap.put(day, ++integer);
            }
        }
        StatisticsVo.CountData countData = new StatisticsVo.CountData(new String[dayCountMap.size()], new Integer[dayCountMap.size()]);
        Set<String> days = dayCountMap.keySet();
        int i = 0;
          for (String day :  days){
              countData.getxData()[i] = day;
              countData.getyData()[i] = dayCountMap.get(day);
              i++;
          }
        vo.setCountData(countData);
        if(satisfactionCount > 0){
            BigDecimal satSum = new BigDecimal(satisfactionSum);
            BigDecimal satCount = new BigDecimal(satisfactionCount);
            vo.setSatisfyData((new BigDecimal(10).multiply((satSum.divide(satCount,2, BigDecimal.ROUND_HALF_UP)))).intValue());
        }else{
            vo.setSatisfyData(100);
        }
    }

    private void makePerData(List<ServiceTicket> tickets, StatisticsVo vo) {
        List<Dictionary> businessTypes = dictionaryService.listByTypeCode(DicTypeContent.BUSINESS_TYPE);
        Map<String, String> busTypes = new HashMap<>(businessTypes.size());
        Map<String, Integer> busTypeNums = new HashMap<>(businessTypes.size());

        for(Dictionary dic : businessTypes){
            busTypes.put(dic.getCode(), dic.getValue());
        }

        for (ServiceTicket ticket: tickets){
            String businessType = ticket.getBusinessType();
            String typeCN = busTypes.get(businessType);
            Integer count = busTypeNums.get(typeCN);
            if(count == null){
                busTypeNums.put(typeCN, 1);
            }else{
                busTypeNums.put(typeCN, ++count);
            }
        }
        List<StatisticsVo.BusinessPercentData> percentDatas = new ArrayList<>(businessTypes.size());
        busTypeNums.forEach((key, val) -> {
            percentDatas.add(new StatisticsVo.BusinessPercentData(key, val));
        });
        vo.setBusinessPercentDatas(percentDatas);

    }

    private List<CommonTreeVo> getChildren(List<Org> orgs) {
        List<CommonTreeVo> treeVos = new ArrayList<>(orgs.size());
        for (Org org : orgs){
            List<Org> subOrgs = org.getChildren();
            CommonTreeVo treeVo = new CommonTreeVo();
            treeVo.setLabel(org.getName());
            treeVo.setValue(String.valueOf(org.getId()));
            treeVo.setChildren(getChildren(subOrgs));
            treeVos.add(treeVo);
        }
        return treeVos;
    }

//    public static void main(String[] args) {
//        DateTime offset = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, -7);
//        DateTime beginOfDay = DateUtil.beginOfDay(offset);
//        System.out.println(beginOfDay);
//    }
}
